package org.sikyon.chocolatebiscuit.model;

import org.junit.Test;
import org.sikyon.chocolatebiscuit.model.entities.Identifiable;
import org.sikyon.chocolatebiscuit.model.entities.User;
import org.sikyon.chocolatebiscuit.model.entities.UserBuilder;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;

public class UserSpec {

    // email, evidently, is the user id
    @Test
    public void aUserIsEqualToAnotherUserIfTheirEmailsAreTheSame() {
        User first = new UserBuilder().email("me@sikyon.com").build();
        User second = new UserBuilder().email("me@sikyon.com").build();

        assertThat("the users are not equal even though their emails are the same", first.equals(second), is(true));
    }

    @Test
    public void aUserIsDifferentToAnotherUserIfTheirEmailsAreNotTheSame() {
        User first = new UserBuilder().email("me@sikyon.com").build();
        User second = new UserBuilder().email("me2@sikyon.com").build();

        assertThat("the users are equal even though their emails are different", first.equals(second), is(false));
    }

    // as stupid as the next to tests may seem, they will help me TDD the equals() code
    @Test
    public void aUserIsNeverEqualToAnObjectOfADifferentClass() {
        User first = new UserBuilder().email("me@sikyon.com").build();
        Object second = new Object();

        assertThat(first.equals(second), is(false));
    }

    @Test
    public void aUserIsEqualToItself() {
        User first = new UserBuilder().email("me@sikyon.com").build();
        assertThat(first.equals(first), is(true));
    }

    @Test
    public void usersWithTheSameEmailGenerateSimilarHashes() {
        User first = new UserBuilder().email("me@sikyon.com").build();
        User second = new UserBuilder().email("me@sikyon.com").build();

        // I already have a test that asserts that the objects are indeed equal
        assertThat(first.hashCode(), is(equalTo(second.hashCode())));
    }

    @Test
    public void theEmailIsTheId() {
        Identifiable<String> user = new UserBuilder().email("me@sikyon.com").build();

        assertThat(user.id(), is(equalTo(((User) user).email())));
    }

    @Test
    public void toStringGeneratesAStringFullyRepresentingTheUser() {
        Identifiable<String> user = new UserBuilder().email("me@sikyon.com").build();

        assertThat(user.toString(), is(equalTo("User:<id>email::me@sikyon.com")));
    }
}
